﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XCoder
{
    /// <summary>
    /// 列架构信息
    /// </summary>
    internal class XColumn
    {
        /// <summary>
        /// 表名称
        /// </summary>
        public string TableName { get; set; }

        /// <summary>
        /// 列名称
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 列位置
        /// </summary>
        public int Ordinal { get; set; }

        /// <summary>
        /// charp数据类型
        /// </summary>
        public string DataType { get; set; }

        /// <summary>
        /// 数据最大长度
        /// </summary>
        public int MaxLength { get; set; }

        /// <summary>
        /// 是否允许空值
        /// </summary>
        public bool AllowDBNull { get; set; }

        /// <summary>
        /// 是否为自动增长列
        /// </summary>
        public bool AutoIncrement { get; set; }

        /// <summary>
        /// 将数据行转换为列架构信息
        /// </summary>
        /// <param name="row"> 数据行 </param>
        /// <param name="dbType"> 数据库类型 </param>
        /// <returns></returns>
        public static XColumn Parse(System.Data.DataRow row, System.Data.DatabaseType dbType)
        {
            XColumn model = new XColumn();
            if (row != null)
            {
                switch (dbType)
                {
                    case System.Data.DatabaseType.SqlServer:
                        #region SqlServer赋值
                        {
                            //  表名称
                            if (row.Table.Columns.Contains("Table_Name"))
                                model.TableName = row["Table_Name"] as string;
                            //  列名称
                            if (row.Table.Columns.Contains("Column_Name"))
                                model.ColumnName = row["Column_Name"] as string;
                            //  列位置
                            if (row.Table.Columns.Contains("ORDINAL_POSITION") && row["ORDINAL_POSITION"] != null && row["ORDINAL_POSITION"] != DBNull.Value)
                                model.Ordinal = (int)row["ORDINAL_POSITION"];
                            //  数据类型
                            if (row.Table.Columns.Contains("DATA_TYPE"))
                                model.DataType = row["DATA_TYPE"] as string;
                            //  是否可空
                            if (row.Table.Columns.Contains("IS_NULLABLE"))
                                model.AllowDBNull = string.Equals((row["IS_NULLABLE"] as string), "YES", StringComparison.CurrentCultureIgnoreCase);
                            //  列数居最大值
                            if (row.Table.Columns.Contains("CHARACTER_MAXIMUM_LENGTH") && row["CHARACTER_MAXIMUM_LENGTH"] != null && row["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
                                model.MaxLength = int.Parse(row["CHARACTER_MAXIMUM_LENGTH"].ToString());
                        }
                        #endregion
                        break;
                    case System.Data.DatabaseType.Oracle:
                        #region Oracle
                        {
                            //  表名称
                            if (row.Table.Columns.Contains("Table_Name"))
                                model.TableName = row["Table_Name"] as string;
                            //  列名称
                            if (row.Table.Columns.Contains("Column_Name"))
                                model.ColumnName = row["Column_Name"] as string;
                            //  列位置
                            if (row.Table.Columns.Contains("ID") && row["ID"] != null && row["ID"] != DBNull.Value)
                                model.Ordinal = int.Parse(row["ID"].ToString());
                            //  数据类型
                            if (row.Table.Columns.Contains("DATATYPE"))
                                model.DataType = row["DATATYPE"] as string;
                            //  是否可空
                            if (row.Table.Columns.Contains("NULLABLE"))
                                model.AllowDBNull = string.Equals((row["NULLABLE"] as string), "Y", StringComparison.CurrentCultureIgnoreCase);
                            //  列数居最大值
                            if (row.Table.Columns.Contains("LENGTH") && row["LENGTH"] != null && row["LENGTH"] != DBNull.Value)
                                model.MaxLength = int.Parse(row["LENGTH"].ToString());
                        }
                        #endregion
                        break;
                    default:
                        #region 公共
                        {
                            //  表名称
                            if (row.Table.Columns.Contains("Table_Name"))
                                model.TableName = row["Table_Name"] as string;
                            //  列名称
                            if (row.Table.Columns.Contains("Column_Name"))
                                model.ColumnName = row["Column_Name"] as string;
                            //  列位置
                            if (row.Table.Columns.Contains("ORDINAL_POSITION") && row["ORDINAL_POSITION"] != null && row["ORDINAL_POSITION"] is int)
                                model.Ordinal = (int)row["ORDINAL_POSITION"];
                            //  数据类型
                            if (row.Table.Columns.Contains("DATA_TYPE") && row["DATA_TYPE"] != null && row["DATA_TYPE"] != DBNull.Value)
                                model.DataType = row["DATA_TYPE"].ToString();
                            //  是否可空
                            if (row.Table.Columns.Contains("IS_NULLABLE"))
                                model.AllowDBNull = string.Equals((row["IS_NULLABLE"] as string), "YES", StringComparison.CurrentCultureIgnoreCase);
                            //  列数居最大值
                            if (row.Table.Columns.Contains("CHARACTER_MAXIMUM_LENGTH") && row["CHARACTER_MAXIMUM_LENGTH"] != null && row["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
                                model.MaxLength = int.Parse(row["CHARACTER_MAXIMUM_LENGTH"].ToString());
                        }
                        #endregion
                        break;
                }
            }
            return model;
        }

        public static System.Collections.Generic.List<XColumn> Parse(System.Data.DataTable source, System.Data.DatabaseType dbType)
        {
            System.Collections.Generic.List<XColumn> models = new System.Collections.Generic.List<XColumn>();
            if (source != null && source.Rows.Count > 0)
            {
                foreach (System.Data.DataRow row in source.Rows)
                {
                    var model = XColumn.Parse(row, dbType);

                    if (dbType == System.Data.DatabaseType.Oracle && (model.ColumnName.Contains("#") || model.ColumnName.Contains("$")))
                        continue;

                    models.Add(model);
                }
            }
            return models;
        }
    }
}
